<!DOCTYPE html>
<html>

<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>jobs58 v4</title>


<style type="text/css">
*{margin:0;padding:0;}
body {
	font:13.34px helvetica,arial,freesans,clean,sans-serif;
	color:black;
	line-height:1.4em;
	background-color: #F8F8F8;
	padding: 0.7em;
}
p {
	margin:1em 0;
	line-height:1.5em;
}
table {
	font-size:inherit;
	font:100%;
	margin:1em;
}
table th{border-bottom:1px solid #bbb;padding:.2em 1em;}
table td{border-bottom:1px solid #ddd;padding:.2em 1em;}
input[type=text],input[type=password],input[type=image],textarea{font:99% helvetica,arial,freesans,sans-serif;}
select,option{padding:0 .25em;}
optgroup{margin-top:.5em;}
pre,code{font:12px Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace;}
pre {
	margin:1em 0;
	font-size:12px;
	background-color:#eee;
	border:1px solid #ddd;
	padding:5px;
	line-height:1.5em;
	color:#444;
	overflow:auto;
	-webkit-box-shadow:rgba(0,0,0,0.07) 0 1px 2px inset;
	-webkit-border-radius:3px;
	-moz-border-radius:3px;border-radius:3px;
}
pre code {
	padding:0;
	font-size:12px;
	background-color:#eee;
	border:none;
}
code {
	font-size:12px;
	background-color:#f8f8ff;
	color:#444;
	padding:0 .2em;
	border:1px solid #dedede;
}
img{border:0;max-width:100%;}
abbr{border-bottom:none;}
a{color:#4183c4;text-decoration:none;}
a:hover{text-decoration:underline;}
a code,a:link code,a:visited code{color:#4183c4;}
h2,h3{margin:1em 0;}
h1,h2,h3,h4,h5,h6{border:0;}
h1{font-size:170%;border-top:4px solid #aaa;padding-top:.5em;margin-top:1.5em;}
h1:first-child{margin-top:0;padding-top:.25em;border-top:none;}
h2{font-size:150%;margin-top:1.5em;border-top:4px solid #e0e0e0;padding-top:.5em;}
h3{margin-top:1em;}
hr{border:1px solid #ddd;}
ul{margin:1em 0 1em 2em;}
ol{margin:1em 0 1em 2em;}
ul li,ol li{margin-top:.5em;margin-bottom:.5em;}
ul ul,ul ol,ol ol,ol ul{margin-top:0;margin-bottom:0;}
blockquote{margin:1em 0;border-left:5px solid #ddd;padding-left:.6em;color:#555;}
dt{font-weight:bold;margin-left:1em;}
dd{margin-left:2em;margin-bottom:1em;}
sup {
    font-size: 0.83em;
    vertical-align: super;
    line-height: 0;
}
kbd {
  display: inline-block;padding: 3px 5px;font-size: 11px;line-height: 10px;color: #555;vertical-align: middle;background-color: #fcfcfc;border: solid 1px #ccc;border-bottom-color: #bbb;border-radius: 3px;box-shadow: inset 0 -1px 0 #bbb;
}
* {
	-webkit-print-color-adjust: exact;
}
@media screen and (min-width: 914px) {
    body {
        width: 854px;
        margin:0 auto;
    }
}
@media print {
	table, pre {
		page-break-inside: avoid;
	}
	pre {
		word-wrap: break-word;
	}
}
</style>

<style type="text/css">
/**
 * prism.js default theme for JavaScript, CSS and HTML
 * Based on dabblet (http://dabblet.com)
 * @author Lea Verou
 */

code[class*="language-"],
pre[class*="language-"] {
	color: black;
	background: none;
	text-shadow: 0 1px white;
	font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
	text-align: left;
	white-space: pre;
	word-spacing: normal;
	word-break: normal;
	word-wrap: normal;
	line-height: 1.5;

	-moz-tab-size: 4;
	-o-tab-size: 4;
	tab-size: 4;

	-webkit-hyphens: none;
	-moz-hyphens: none;
	-ms-hyphens: none;
	hyphens: none;
}

pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
	text-shadow: none;
	background: #b3d4fc;
}

pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
code[class*="language-"]::selection, code[class*="language-"] ::selection {
	text-shadow: none;
	background: #b3d4fc;
}

@media print {
	code[class*="language-"],
	pre[class*="language-"] {
		text-shadow: none;
	}
}

/* Code blocks */
pre[class*="language-"] {
	padding: 1em;
	margin: .5em 0;
	overflow: auto;
}

:not(pre) > code[class*="language-"],
pre[class*="language-"] {
	background: #f5f2f0;
}

/* Inline code */
:not(pre) > code[class*="language-"] {
	padding: .1em;
	border-radius: .3em;
	white-space: normal;
}

.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
	color: slategray;
}

.token.punctuation {
	color: #999;
}

.namespace {
	opacity: .7;
}

.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
	color: #905;
}

.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
	color: #690;
}

.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
	color: #a67f59;
	background: hsla(0, 0%, 100%, .5);
}

.token.atrule,
.token.attr-value,
.token.keyword {
	color: #07a;
}

.token.function {
	color: #DD4A68;
}

.token.regex,
.token.important,
.token.variable {
	color: #e90;
}

.token.important,
.token.bold {
	font-weight: bold;
}
.token.italic {
	font-style: italic;
}

.token.entity {
	cursor: help;
}
</style>


</head>

<body>

<p>参考代码：<a href="http://git.oschina.net/crossin/crawler/blob/master/ex8_jobs58/" target="_blank">http://git.oschina.net/crossin/crawler/blob/master/ex8_jobs58/</a></p>

<p><a href="http://git.oschina.net/crossin/crawler/blob/master/ex8_jobs58/jobs58_v2.html" target="_blank">完整展示页面 HTML 代码</a></p>

<h2 id="toc_0">1. ECharts</h2>

<p>ECharts 是一个纯 JavaScript 的图表库，可以流畅的运行在 PC 和移动设备上，兼容当前绝大部分浏览器，提供直观，生动，可交互，可高度个性化定制的数据可视化图表。</p>

<p>ECharts 提供了常规的<strong>折线图</strong>，<strong>柱状图</strong>，<strong>散点图</strong>，<strong>饼图</strong>，<strong>K线图</strong>，用于统计的<strong>盒形图</strong>，用于地理数据可视化的<strong>地图</strong>，<strong>热力图</strong>，<strong>线图</strong>，用于关系数据可视化的<strong>关系图</strong>，<strong>treemap</strong>，多维数据可视化的<strong>平行坐标</strong>，还有用于 BI 的<strong>漏斗图</strong>，<strong>仪表盘</strong>，并且支持图与图之间的混搭。</p>

<p>我们用爬虫获取了数据之后，可以</p>

<h3 id="toc_1">使用指南</h3>

<h4 id="toc_2">获取 ECharts</h4>

<p>最方便的方式就是通过 <a href="http://echarts.baidu.com/download.html" target="_blank">官网下载</a>，根据不同需求可选择不同版本。</p>

<h4 id="toc_3">引入 ECharts</h4>

<p>在 HTML 代码中，像普通的 JavaScript 库一样用 <code>&lt;script&gt;</code> 标签引入：</p>

<div><pre><code class="language-markup">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
    &lt;!-- 引入 ECharts 文件 --&gt;
    &lt;script src=&quot;echarts.min.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;/html&gt;</code></pre></div>

<h4 id="toc_4">绘制图表</h4>

<p>在 ECharts 中绘制图表主要有 2 个步骤：</p>

<ol>
<li><p>创建一个具备高宽的 DOM 容器：</p>

<div><pre><code class="language-markup">&lt;body&gt;
    &lt;!-- 为 ECharts 准备一个具备大小（宽高）的 DOM --&gt;
    &lt;div id=&quot;main&quot; style=&quot;width: 600px;height:400px;&quot;&gt;&lt;/div&gt;
&lt;/body&gt;</code></pre></div></li>
<li><p>通过 <code>echarts.init</code> 方法初始化一个 echarts 实例并通过 <code>setOption</code> 方法生成图表。以一个简单的柱状图为例：</p>

<div><pre><code class="language-markup">&lt;script type=&quot;text/javascript&quot;&gt;
    // 基于准备好的dom，初始化echarts实例
    var myChart = echarts.init(document.getElementById(&#39;main&#39;));

    // 指定图表的配置项和数据
    var option = {
        title: {
            text: &#39;ECharts 入门示例&#39;
        },
        tooltip: {},
        legend: {
            data:[&#39;销量&#39;]
        },
        xAxis: {
            data: [&quot;衬衫&quot;,&quot;羊毛衫&quot;,&quot;雪纺衫&quot;,&quot;裤子&quot;,&quot;高跟鞋&quot;,&quot;袜子&quot;]
        },
        yAxis: {},
        series: [{
            name: &#39;销量&#39;,
            type: &#39;bar&#39;,
            data: [5, 20, 36, 10, 10, 20]
        }]
    };

    // 使用刚指定的配置项和数据显示图表。
    myChart.setOption(option);
&lt;/script&gt;</code></pre></div></li>
</ol>

<h4 id="toc_5">效果</h4>

<p><img src="http://git.oschina.net/crossin/crawler/raw/master/stuff/echarts.png" style="width:100%" alt=""></p>

<p>更多的类型的图表，请参考官方教程中的示例。选择对应的示例，然后按照上述两个步骤，向其中添加自己的数据即可。</p>

<h3 id="toc_6">参考资料</h3>

<ol>
<li><a href="http://echarts.baidu.com" target="_blank">ECharts 官方文档</a></li>
<li><a href="http://echarts.baidu.com/tutorial.html" target="_blank">教程 - ECharts 官方文档</a></li>
<li><a href="http://echarts.baidu.com/examples.html" target="_blank">示例 - ECharts 官方文档</a></li>
</ol>

<h2 id="toc_7">2. HTML &lt;script&gt; 标签</h2>

<p>HTML 代码中的 <code>&lt;script&gt;</code> 标签用于定义客户端脚本，比如 JavaScript。它既可以直接包含脚本语句，也可以通过 <code>src</code> 属性指向外部脚本文件。需要在 <code>type</code> 属性中指定脚本的类型。</p>

<p>所有浏览器都支持 <code>&lt;script&gt;</code> 标签。</p>

<h3 id="toc_8">示例</h3>

<p>直接使用 js 代码语句：</p>

<div><pre><code class="language-markup">&lt;script type=&quot;text/javascript&quot;&gt;
    document.write(&quot;Hello World!&quot;)
&lt;/script&gt;</code></pre></div>

<p>这段 script 标签会在页面上增加文本 <code>Hello World!</code>。</p>

<p>引入外部脚本文件：</p>

<div><pre><code class="language-markup">&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/echarts/3.5.4/echarts.min.js&quot;&gt;&lt;/script&gt;</code></pre></div>

<p>这段 script 引入了网络上的 echarts 库文件。</p>

<h3 id="toc_9">参考资料</h3>

<ol>
<li><a href="http://www.w3school.com.cn/tags/tag_script.asp" target="_blank">HTML &lt;script&gt; 标签 - W3School</a></li>
<li><a href="http://www.runoob.com/tags/tag-script.html" target="_blank">HTML &lt;script&gt; 标签 - 菜鸟教程</a></li>
</ol>

<h2 id="toc_10">3. Python json</h2>

<p>JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。</p>

<p>Python 中可以使用 json 模块来对 JSON 数据进行编解码。</p>

<h3 id="toc_11">示例</h3>

<p>将 JSON 数据转为 dict 对象：</p>

<div><pre><code class="language-python">&gt;&gt;&gt; import json
&gt;&gt;&gt; s = &#39;{&quot;name&quot;: &quot;Crossin&quot;, &quot;age&quot;: 18}&#39;
&gt;&gt;&gt; d = json.loads(s)
&gt;&gt;&gt; d
{&#39;age&#39;: 18, &#39;name&#39;: &#39;Crossin&#39;}
&gt;&gt;&gt; type(d)
dict</code></pre></div>

<p>将 dict 对象转为 JSON 数据：</p>

<div><pre><code class="language-python">&gt;&gt;&gt; d = {
...     &#39;name&#39;: &#39;Crossin&#39;,
...     &#39;age&#39;: 18
... }
&gt;&gt;&gt; s = json.dumps(d)
&gt;&gt;&gt; s
&#39;{&quot;name&quot;: &quot;Crossin&quot;, &quot;age&quot;: 18}&#39;
&gt;&gt;&gt; type(s)
str</code></pre></div>

<p>如果要直接读写 json 格式的文件，可以使用 <code>json.dump()</code> 和 <code>json.load()</code> 方法，注意方法名中有没有 <strong>s</strong> 的区别：</p>

<div><pre><code class="language-python"># 写入字典对象 d 到文件 data.json
with open(&#39;data.json&#39;, &#39;w&#39;) as f:
    json.dump(d, f)

# 从文件 data.json 中读取数据到字典对象 d
with open(&#39;data.json&#39;, &#39;r&#39;) as f:
    d = json.load(f)</code></pre></div>

<h3 id="toc_12">参考资料</h3>

<ol>
<li><a href="http://www.runoob.com/python3/python3-json.html" target="_blank">Python3 JSON 数据解析 - 菜鸟教程</a></li>
<li><a href="http://usyiyi.cn/translate/python_352/library/json.html" target="_blank">json - Python 标准库</a></li>
</ol>

<h2 id="toc_13">4. dict.get</h2>

<p>Python 中的字典类型，可以通过中括号操作符，根据键名访问对应的值。但如果给定的键名不存在，则会报 KeyError 的异常：</p>

<div><pre><code class="language-python">&gt;&gt;&gt; data = {&#39;name&#39;: &#39;Crossin&#39;}
&gt;&gt;&gt; data[&#39;age&#39;]
Traceback (most recent call last):
  File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
KeyError: &#39;age&#39;</code></pre></div>

<p>字典类型还提供了另一种取值的内置方法：<code>get</code>，可以避免键名不存在时的异常。</p>

<h3 id="toc_14">语法</h3>

<div><pre><code class="language-python">get(key[, default])</code></pre></div>

<p>如果 key 在字典里，返回 key 对应的值，否则返回 default 值。如果没有提供 default，默认返回 None。此方法不会引发 KeyError。</p>

<h3 id="toc_15">示例</h3>

<div><pre><code class="language-python">&gt;&gt;&gt; data = {&#39;name&#39;: &#39;Crossin&#39;}
&gt;&gt;&gt; print(data.get(&#39;age&#39;))
None
&gt;&gt;&gt; data.get(&#39;age&#39;, 0)
0</code></pre></div>

<h3 id="toc_16">参考资料</h3>

<ol>
<li><a href="http://usyiyi.cn/documents/python_352/library/stdtypes.html#mapping-types-dict" target="_blank">dict - Python 标准库</a></li>
<li><a href="http://www.runoob.com/python3/python3-dictionary.html" target="_blank">Python3 字典</a></li>
</ol>

<h2 id="toc_17">5. collections.Counter</h2>

<p>Counter 是 dict 的子类，用于计数可哈希对象。它是一个无序的容器，元素被存储为字典键，它们的计数被存储为字典值。计数允许包括零或负计数的任何整数值。</p>

<h3 id="toc_18">创建</h3>

<p>Counter 有多种初始化方法：</p>

<div><pre><code class="language-python">&gt;&gt;&gt; from collections import Counter
&gt;&gt;&gt; c = Counter([&#39;eggs&#39;, &#39;ham&#39;])
&gt;&gt;&gt; c
Counter({&#39;eggs&#39;: 1, &#39;ham&#39;: 1})
&gt;&gt;&gt; Counter(&#39;gallahad&#39;)
Counter({&#39;a&#39;: 3, &#39;l&#39;: 2, &#39;g&#39;: 1, &#39;h&#39;: 1, &#39;d&#39;: 1})
&gt;&gt;&gt; Counter({&#39;red&#39;: 4, &#39;blue&#39;: 2})
Counter({&#39;red&#39;: 4, &#39;blue&#39;: 2})
&gt;&gt;&gt; Counter(cats=4, dogs=8)
Counter({&#39;dogs&#39;: 8, &#39;cats&#39;: 4})</code></pre></div>

<h3 id="toc_19">最多计数</h3>

<p><code>most_common([n])</code> 返回 n 个数量最多的元素及其计数的列表，从最多到最少。如果不提供参数则返回计数器中所有元素。具有相等计数的元素是任意排序的：</p>

<div><pre><code class="language-python">&gt;&gt;&gt; Counter(&#39;abracadabra&#39;).most_common(3)  
[(&#39;a&#39;, 5), (&#39;r&#39;, 2), (&#39;b&#39;, 2)]</code></pre></div>

<h3 id="toc_20">参考资料</h3>

<ol>
<li><a href="https://mp.weixin.qq.com/s?__biz=MjM5MDEyMDk4Mw==&amp;mid=502682687&amp;idx=2&amp;sn=f2c8b8d3c7d14de76922c87a7aec2471&amp;chksm=3e4b5947093cd05172099222d1c4d60d239f9d84a2a6a84184b88e5fe69abc3d13f8bd88f156&amp;scene=0&amp;key=06572546e28007a7b41912cd7689101eed778f24dca5d934094c81029f6dab31d0ea575f787d2b1d5ddcd75ee67678cf283930a3325cfdde597edd301c14d4ce6bc79af2391818ee2a9d112a2078d6b8&amp;ascene=0&amp;uin=MjQwMjY2NzU%3D&amp;devicetype=iMac+MacBookPro11%2C5+OSX+OSX+10.11.6+build(15G1421)&amp;version=12020610&amp;nettype=WIFI&amp;fontScale=100&amp;pass_ticket=JU2wWAulK08PAzZlBpl50%2Bgbk3lm5hy1uVIk9%2BbYAco%3D" target="_blank">计数器 Counter</a></li>
<li><a href="http://usyiyi.cn/documents/python_352/library/collections.html#counter-objects" target="_blank">Counter 对象 - Python 标准库</a></li>
</ol>

<h2 id="toc_21">6. ECharts 地图</h2>

<p>在使用 ECharts 的地图展示时，需要从官网上额外下载所需区域的地图数据包：<a href="http://echarts.baidu.com/download-map.html" target="_blank">地图下载</a></p>

<p>数据包有 JS 和 JSON 两种类型。</p>

<h3 id="toc_22">引入方式</h3>

<p>JavaScript 引入示例：</p>

<div><pre><code class="language-javascript">&lt;script src=&quot;echarts.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;map/js/china.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
var chart = echarts.init(document.getElementById(&#39;main&#39;));
chart.setOption({
    series: [{
        type: &#39;map&#39;,
        map: &#39;china&#39;
    }]
});
&lt;/script&gt;</code></pre></div>

<p>JSON 引入示例：</p>

<div><pre><code class="language-javascript">$.get(&#39;map/json/china.json&#39;, function (chinaJson) {
    echarts.registerMap(&#39;china&#39;, chinaJson);
    var chart = echarts.init(document.getElementById(&#39;main&#39;));
    chart.setOption({
        series: [{
            type: &#39;map&#39;,
            map: &#39;china&#39;
        }]
    });
});</code></pre></div>

<p>特别提醒一下：在代码中配置地图信息时，一定要注意使用正确的名称。比如绘制上海地图时，要指明 <code>map</code> 或者 <code>mapType</code> 属性为 <code>上海</code>，如使用 <code>shanghai</code> 则无法显示。另外对于区域中的名称也必须为 <code>黄浦区</code>、<code>徐汇区</code> 等，否则也将不显示在地图上。</p>

<h3 id="toc_23">参考资料</h3>

<ol>
<li><a href="http://echarts.baidu.com/download-map.html" target="_blank">地图下载 - ECharts 官方文档</a></li>
<li><a href="http://echarts.baidu.com/examples.html#chart-type-map" target="_blank">地图示例 - ECharts 官方文档</a></li>
</ol>



<script type="text/javascript">
var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-(\w+)\b/i,t=0,n=_self.Prism={util:{encode:function(e){return e instanceof a?new a(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function(e){var t=n.util.type(e);switch(t){case"Object":var a={};for(var r in e)e.hasOwnProperty(r)&&(a[r]=n.util.clone(e[r]));return a;case"Array":return e.map&&e.map(function(e){return n.util.clone(e)})}return e}},languages:{extend:function(e,t){var a=n.util.clone(n.languages[e]);for(var r in t)a[r]=t[r];return a},insertBefore:function(e,t,a,r){r=r||n.languages;var l=r[e];if(2==arguments.length){a=arguments[1];for(var i in a)a.hasOwnProperty(i)&&(l[i]=a[i]);return l}var o={};for(var s in l)if(l.hasOwnProperty(s)){if(s==t)for(var i in a)a.hasOwnProperty(i)&&(o[i]=a[i]);o[s]=l[s]}return n.languages.DFS(n.languages,function(t,n){n===r[e]&&t!=e&&(this[t]=o)}),r[e]=o},DFS:function(e,t,a,r){r=r||{};for(var l in e)e.hasOwnProperty(l)&&(t.call(e,l,e[l],a||l),"Object"!==n.util.type(e[l])||r[n.util.objId(e[l])]?"Array"!==n.util.type(e[l])||r[n.util.objId(e[l])]||(r[n.util.objId(e[l])]=!0,n.languages.DFS(e[l],t,l,r)):(r[n.util.objId(e[l])]=!0,n.languages.DFS(e[l],t,null,r)))}},plugins:{},highlightAll:function(e,t){var a={callback:t,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};n.hooks.run("before-highlightall",a);for(var r,l=a.elements||document.querySelectorAll(a.selector),i=0;r=l[i++];)n.highlightElement(r,e===!0,a.callback)},highlightElement:function(t,a,r){for(var l,i,o=t;o&&!e.test(o.className);)o=o.parentNode;o&&(l=(o.className.match(e)||[,""])[1],i=n.languages[l]),t.className=t.className.replace(e,"").replace(/\s+/g," ")+" language-"+l,o=t.parentNode,/pre/i.test(o.nodeName)&&(o.className=o.className.replace(e,"").replace(/\s+/g," ")+" language-"+l);var s=t.textContent,u={element:t,language:l,grammar:i,code:s};if(!s||!i)return n.hooks.run("complete",u),void 0;if(n.hooks.run("before-highlight",u),a&&_self.Worker){var c=new Worker(n.filename);c.onmessage=function(e){u.highlightedCode=e.data,n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,r&&r.call(u.element),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},c.postMessage(JSON.stringify({language:u.language,code:u.code,immediateClose:!0}))}else u.highlightedCode=n.highlight(u.code,u.grammar,u.language),n.hooks.run("before-insert",u),u.element.innerHTML=u.highlightedCode,r&&r.call(t),n.hooks.run("after-highlight",u),n.hooks.run("complete",u)},highlight:function(e,t,r){var l=n.tokenize(e,t);return a.stringify(n.util.encode(l),r)},tokenize:function(e,t){var a=n.Token,r=[e],l=t.rest;if(l){for(var i in l)t[i]=l[i];delete t.rest}e:for(var i in t)if(t.hasOwnProperty(i)&&t[i]){var o=t[i];o="Array"===n.util.type(o)?o:[o];for(var s=0;s<o.length;++s){var u=o[s],c=u.inside,g=!!u.lookbehind,h=!!u.greedy,f=0,d=u.alias;u=u.pattern||u;for(var p=0;p<r.length;p++){var m=r[p];if(r.length>e.length)break e;if(!(m instanceof a)){u.lastIndex=0;var y=u.exec(m),v=1;if(!y&&h&&p!=r.length-1){var b=r[p+1].matchedStr||r[p+1],k=m+b;if(p<r.length-2&&(k+=r[p+2].matchedStr||r[p+2]),u.lastIndex=0,y=u.exec(k),!y)continue;var w=y.index+(g?y[1].length:0);if(w>=m.length)continue;var _=y.index+y[0].length,P=m.length+b.length;if(v=3,P>=_){if(r[p+1].greedy)continue;v=2,k=k.slice(0,P)}m=k}if(y){g&&(f=y[1].length);var w=y.index+f,y=y[0].slice(f),_=w+y.length,S=m.slice(0,w),O=m.slice(_),j=[p,v];S&&j.push(S);var A=new a(i,c?n.tokenize(y,c):y,d,y,h);j.push(A),O&&j.push(O),Array.prototype.splice.apply(r,j)}}}}}return r},hooks:{all:{},add:function(e,t){var a=n.hooks.all;a[e]=a[e]||[],a[e].push(t)},run:function(e,t){var a=n.hooks.all[e];if(a&&a.length)for(var r,l=0;r=a[l++];)r(t)}}},a=n.Token=function(e,t,n,a,r){this.type=e,this.content=t,this.alias=n,this.matchedStr=a||null,this.greedy=!!r};if(a.stringify=function(e,t,r){if("string"==typeof e)return e;if("Array"===n.util.type(e))return e.map(function(n){return a.stringify(n,t,e)}).join("");var l={type:e.type,content:a.stringify(e.content,t,r),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:r};if("comment"==l.type&&(l.attributes.spellcheck="true"),e.alias){var i="Array"===n.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(l.classes,i)}n.hooks.run("wrap",l);var o="";for(var s in l.attributes)o+=(o?" ":"")+s+'="'+(l.attributes[s]||"")+'"';return"<"+l.tag+' class="'+l.classes.join(" ")+'" '+o+">"+l.content+"</"+l.tag+">"},!_self.document)return _self.addEventListener?(_self.addEventListener("message",function(e){var t=JSON.parse(e.data),a=t.language,r=t.code,l=t.immediateClose;_self.postMessage(n.highlight(r,n.languages[a],a)),l&&_self.close()},!1),_self.Prism):_self.Prism;var r=document.currentScript||[].slice.call(document.getElementsByTagName("script")).pop();return r&&(n.filename=r.src,document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",n.highlightAll)),_self.Prism}();"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
</script>

<script type="text/javascript">
Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:{pattern:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/};
</script>

<script type="text/javascript">
Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i}),Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^\/])\/(?!\/)(\[.+?]|\\.|[^\/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}}),Prism.languages.insertBefore("javascript","class-name",{"template-string":{pattern:/`(?:\\\\|\\?[^\\])*?`/,greedy:!0,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/(<script[\w\W]*?>)[\w\W]*?(?=<\/script>)/i,lookbehind:!0,inside:Prism.languages.javascript,alias:"language-javascript"}}),Prism.languages.js=Prism.languages.javascript;
</script>

<script type="text/javascript">
Prism.languages.python={"triple-quoted-string":{pattern:/"""[\s\S]+?"""|'''[\s\S]+?'''/,alias:"string"},comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},string:/("|')(?:\\?.)*?\1/,"function":{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)[a-z0-9_]+/i,lookbehind:!0},keyword:/\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/,"boolean":/\b(?:True|False)\b/,number:/\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,punctuation:/[{}[\];(),.:]/};
</script>

<script type="text/javascript">
Prism.languages.markup={comment:/<!--[\w\W]*?-->/,prolog:/<\?[\w\W]+?\?>/,doctype:/<!DOCTYPE[\w\W]+?>/,cdata:/<!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/<\/?(?!\d)[^\s>\/=.$<]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&amp;/,"&"))}),Prism.languages.xml=Prism.languages.markup,Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup;
</script>


</body>

</html>
